import re
import yaml
from urllib.parse import urlparse
from core.utils.path_resolver import (
    resolve_path,
    resolve_config_path,
    resolve_sample_path
)
class RequestMutator:
    def __init__(self, request_file, rules_file):
        request_path = resolve_path('samples', 'original_request.txt')
        rules_path = resolve_path('conf', 'mutate_rules.yaml')
        self.original_request = self.parse_request_file(request_file)
        self.rules = self.load_rules(rules_file)
        
    def parse_request_file(self, file_path):
        with open(file_path, 'r', encoding='gbk') as f:
            content = f.read()
            
        # 解析请求方法、URL、Headers、Body
        method, url, headers, body = self._parse_http_request(content)
        return {
            'method': method,
            'url': url,
            'headers': headers,
            'body': body
        }
    
    def _parse_http_request(self, raw_request):
        lines = raw_request.strip().split('\n')
            # 使用 maxsplit=2 确保只分割前两个空格
        parts = lines[0].split(maxsplit=2)
        if len(parts) < 3:
            raise ValueError("Invalid HTTP request line format")
    
        method, path, _ = parts  # 安全解包
        url = urlparse(path).geturl()
        
        headers = {}
        body = []
        header_end = False
        
        for line in lines[1:]:
            if not line.strip():
                header_end = True
                continue
            if not header_end:
                key, val = line.split(':', 1)
                headers[key.strip()] = val.strip()
            else:
                body.append(line)
        
        return method, url, headers, '\n'.join(body)
    # 加载规则
    def load_rules(self, rules_file):
        with open(rules_file, 'r') as f:
            return yaml.safe_load(f)
    
    def mutate_header(self):
        # 实现Header变异逻辑
        mutated = self.original_request.copy()
        mutated['headers']['X-Forwarded-For'] = '127.0.0.1'
        mutated['headers'].pop('Content-Length', None)
        return mutated
    
    def mutate_filename(self):
        # 实现文件名变异逻辑
        body = self.original_request['body']
        mutated_body = re.sub(
            r'filename="([^"]+)"',
            lambda m: f'filename="{m.group(1)}.php"',
            body
        )
        return self._create_mutated_request(mutated_body)
    
    def _create_mutated_request(self, new_body):
        return {
            **self.original_request,
            'body': new_body,
            'headers': {
                **self.original_request['headers'],
                'Content-Length': str(len(new_body))
            }
        }
    def advanced_mutations(self, rule):
        mutated = self.original_request.copy()
        if rule['type'] == 'filename':
            mutated_body = re.sub(
                rule['pattern'],
                rule['replace'],
                mutated['body'],
                flags=re.IGNORECASE
            )
            return self._create_mutated_request(mutated_body)
        
        elif rule['type'] == 'body':
            mutated['body'] = re.sub(
                rule['pattern'],
                rule['replace'],
                mutated['body']
            )
            return mutated